home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / sed.arc / sedcomp.c < prev    next >
C/C++ Source or Header  |  1989-03-06  |  37KB  |  830 lines

  1. #if 0                /* SAJ */
  2. #include "compiler.h"
  3. #ifdef LATTICE
  4. #define void int
  5. #endif
  6. #endif                /* SAJ */
  7.  
  8. #include "debug.h"
  9. /* sedcomp.c -- stream editor main and compilation phase
  10.  
  11.    The stream editor compiles its command input  (from files or -e options)
  12. into an internal form using compile() then executes the compiled form using
  13. execute(). Main() just initializes data structures, interprets command line
  14. options, and calls compile() and execute() in appropriate sequence.
  15.    The data structure produced by compile() is an array of compiled-command
  16. structures (type sedcmd).  These contain several pointers into pool[], the
  17. regular-expression and text-data pool, plus a command code and g & p flags.
  18. In the special case that the command is a label the struct  will hold a ptr
  19. into the labels array labels[] during most of the compile,  until resolve()
  20. resolves references at the end.
  21.    The operation of execute() is described in its source module. 
  22.  
  23. ==== Written for the GNU operating system by Eric S. Raymond ==== */
  24.  
  25. #include <stdio.h>              /* uses getc, fprintf, fopen, fclose */
  26. #include "sed.h"                /* command type struct and name defines */
  27.  
  28. /* imported functions */
  29. extern int strcmp();            /* test strings for equality */
  30. extern void execute();          /* execute compiled command */
  31.  
  32. /***** public stuff ******/
  33.  
  34. #define MAXCMDS         200     /* maximum number of compiled commands */
  35. #define MAXLINES        256     /* max # numeric addresses to compile */ 
  36.  
  37. /* main data areas */
  38. char    linebuf[MAXBUF+1];      /* current-line buffer */
  39. sedcmd  cmds[MAXCMDS+1];        /* hold compiled commands */
  40. long    linenum[MAXLINES];      /* numeric-addresses table */
  41.  
  42. /* miscellaneous shared variables */ 
  43. int     nflag;                  /* -n option flag */
  44. int     eargc;                  /* scratch copy of argument count */
  45. sedcmd  *pending        = NULL; /* next command to be executed */
  46. char    bits[]          = {1,2,4,8,16,32,64,128};
  47.  
  48. /***** module common stuff *****/
  49.  
  50. #define POOLSIZE        10000   /* size of string-pool space */
  51. #define WFILES          10      /* max # w output files that can be compiled */
  52. #define RELIMIT         256     /* max chars in compiled RE */
  53. #define MAXDEPTH        20      /* maximum {}-nesting level */
  54. #define MAXLABS         50      /* max # of labels that can be handled */
  55.  
  56. #define SKIPWS(pc)      while ((*pc==' ') || (*pc=='\t')) pc++
  57. #define ABORT(msg)      (fprintf(stderr, msg, linebuf), exit(2))
  58. #define IFEQ(x, v)      if (*x == v) x++ , /* do expression */
  59.  
  60. /* error messages */
  61. static char     AGMSG[] = "sed: garbled address %s\n";
  62. static char     CGMSG[] = "sed: garbled command %s\n";
  63. static char     TMTXT[] = "sed: too much text: %s\n";
  64. static char     AD1NG[] = "sed: no addresses allowed for %s\n";
  65. static char     AD2NG[] = "sed: only one address allowed for %s\n";
  66. static char     TMCDS[] = "sed: too many commands, last was %s\n";
  67. static char     COCFI[] = "sed: cannot open command-file %s\n";
  68. static char     UFLAG[] = "sed: unknown flag %c\n";
  69. static char     COOFI[] = "sed: cannot open %s\n";
  70. static char     CCOFI[] = "sed: cannot create %s\n";
  71. static char     ULABL[] = "sed: undefined label %s\n";
  72. static char     TMLBR[] = "sed: too many {'s\n";
  73. static char     FRENL[] = "sed: first RE must be non-null\n";
  74. static char     NSCAX[] = "sed: no such command as %s\n";
  75. static char     TMRBR[] = "sed: too many }'s\n";
  76. static char     DLABL[] = "sed: duplicate label %s\n";
  77. static char     TMLAB[] = "sed: too many labels: %s\n";
  78. static char     TMWFI[] = "sed: too many w files\n";
  79. static char     REITL[] = "sed: RE too long: %s\n";
  80. static char     TMLNR[] = "sed: too many line numbers\n";
  81. static char     TRAIL[] = "sed: command \"%s\" has trailing garbage\n";
  82.  
  83. typedef struct                  /* represent a command label */
  84. {
  85.         char            *name;          /* the label name */
  86.         sedcmd          *last;          /* it's on the label search list */  
  87.         sedcmd          *address;       /* pointer to the cmd it labels */
  88. }
  89. label;
  90.  
  91. /* label handling */
  92. static label    labels[MAXLABS];        /* here's the label table */
  93. static label    *lab    = labels + 1;   /* pointer to current label */
  94. static label    *lablst = labels;       /* header for search list */
  95.  
  96. /* string pool for regular expressions, append text, etc. etc. */
  97. static char     pool[POOLSIZE];                 /* the pool */
  98. static char     *fp     = pool;                 /* current pool pointer */
  99. static char     *poolend = pool + POOLSIZE;     /* pointer past pool end */
  100.  
  101. /* compilation state */
  102. static FILE     *cmdf   = NULL;         /* current command source */
  103. static char     *cp     = linebuf;      /* compile pointer */
  104. static sedcmd   *cmdp   = cmds;         /* current compiled-cmd ptr */
  105. static char     *lastre = NULL;         /* old RE pointer */
  106. static int      bdepth  = 0;            /* current {}-nesting level */
  107. static int      bcount  = 0;            /* # tagged patterns in current RE */
  108. static char     **eargv;                /* scratch copy of argument list */
  109.  
  110. /* compilation flags */
  111. static int      eflag;                  /* -e option flag */
  112. static int      gflag;                  /* -g option flag */
  113.  
  114.  
  115. main(argc, argv)
  116. /* main sequence of the stream editor */
  117. int     argc;
  118. char    *argv[];
  119. {
  120.         void compile(), resolve();
  121.  
  122.         eargc   = argc;         /* set local copy of argument count */
  123.         eargv   = argv;         /* set local copy of argument list */
  124.         cmdp->addr1 = pool;     /* 1st addr expand will be at pool start */
  125.         if (eargc == 1)
  126.                 exit(0);        /* exit immediately if no arguments */
  127. PASS("main(): setup");
  128.         /* scan through the arguments, interpreting each one */
  129.         while ((--eargc > 0) && (**++eargv == '-'))
  130.                 switch (eargv[0][1])
  131.                 {
  132.                 case 'e':
  133.                         eflag++; compile();     /* compile with e flag on */
  134.                         eflag = 0;
  135.                         continue;               /* get another argument */
  136.                 case 'f':
  137.                         if (eargc-- <= 0)       /* barf if no -f file */
  138.                                 exit(2);
  139.                         if ((cmdf = fopen(*++eargv, "r")) == NULL)
  140.                         {
  141.                                 fprintf(stderr, COCFI, *eargv);
  142.                                 exit(2);
  143.                         }
  144.                         compile();      /* file is O.K., compile it */
  145.                         fclose(cmdf);
  146.                         continue;       /* go back for another argument */
  147.                 case 'g':
  148.                         gflag++;        /* set global flag on all s cmds */
  149.                         continue;
  150.                 case 'n':
  151.                         nflag++;        /* no print except on p flag or w */
  152.                         continue;
  153.                 default:
  154.                         fprintf(stdout, UFLAG, eargv[0][1]);
  155.                         continue;
  156.                 }
  157.  
  158. PASS("main(): argscan");
  159.  
  160.         if (cmdp == cmds)       /* no commands have been compiled */
  161.         {
  162.                 eargv--; eargc++;
  163.                 eflag++; compile(); eflag = 0;
  164.                 eargv++; eargc--;
  165.         }
  166.  
  167.         if (bdepth)     /* we have unbalanced squigglies */
  168.                 ABORT(TMLBR);
  169.  
  170.         lablst->address = cmdp; /* set up header of label linked list */
  171.         resolve();              /* resolve label table indirections */
  172. PASS("main(): resolve");
  173.         if (eargc <= 0)         /* if there were no -e commands */
  174.                 execute(NULL);  /*   execute commands from stdin only */
  175.         else while(--eargc>=0)  /* else execute only -e commands */
  176.                 execute(*eargv++);
  177. PASS("main(): end & exit OK");
  178.         exit(0);                /* everything was O.K. if we got here */
  179. }
  180.  
  181.  
  182. #define H       0x80    /* 128 bit, on if there's really code for command */
  183. #define LOWCMD  56      /* = '8', lowest char indexed in cmdmask */ 
  184.  
  185. /* indirect through this to get command internal code, if it exists */
  186. static char     cmdmask[] =
  187. {
  188.         0,      0,      H,      0,      0,      H+E